﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using AnjLab.SyncIT.Core.Api;
using AnjLab.SyncIT.Core.Data.Outlook;

namespace AnjLab.SyncIT.Core.Data.Trac
{
    public class Ticket : ISourceTask
    {
        public string Status { get; set;}
        public string Description { get; set;}
        public string Reporter { get; set; }
        public string CC { get; set;}
        public string Component { get; set;}
        public string Summary { get; set;}
        public string Priority { get; set; }
        public string Keywords { get; set; }
        public string Version { get; set;}
        public string Milestone { get; set; }
        public string Owner { get; set;}
        public string Type { get; set;}
        public string Severity { get; set;}
        public string ID { get; set;}
        public string StartDate { get; set; }
        public string EndDate { get; set; }

        public Importance Importance
        {
            get
            {
                switch (Priority)
                {
                    case "blocker":
                    case "critical":
                    case "major":
                        return Api.Importance.High;

                    case "minor":
                    case "trivial":
                        return Api.Importance.Low;
                }

                return Api.Importance.Normal;
            }
        }

        public string Resolution { get; set; }

        public static Ticket From(XElement elem)
        {
            var res = new Ticket {Description = ""};
            var elements = elem.Elements();
            res.ID = elements.First().Element("string").Value;

            var attributes = elements.ElementAt(3).Element("struct").Elements();

            var mappings = new Dictionary<string, Func<string, string>> {
                                                                            {"status", v => res.Status = v},
                                                                            {"description", v => res.Description = v},
                                                                            {"reporter", v => res.Reporter = v},
                                                                            {"cc", v => res.CC = v},
                                                                            {"resolution", v => res.Resolution = v},
                                                                            {"component", v => res.Component = v},
                                                                            {"summary", v => res.Summary = v},
                                                                            {"priority", v => res.Priority = v},
                                                                            {"keywords", v => res.Keywords = v},
                                                                            {"version", v => res.Version = v},
                                                                            {"milestone", v => res.Milestone = v},
                                                                            {"owner", v => res.Owner = v},
                                                                            {"type", v => res.Type = v},
                                                                            {"severity", v => res.Severity = v},
                                                                        };

            foreach (var xElement in attributes)
            {
                var value = xElement.Element("value").Value;
                var name = xElement.Element("name").Value;

                Func<string, string> action;
                if (mappings.TryGetValue(name, out action)) {
                    action(value);
                } else {
                    Console.WriteLine("unmapped {0}", name);
                }
            }
            return res;
        }

        public string RawDescription
        {
            get { return Description.Replace("#", "#ProjectBase#/ticket/"); }
        }

        public bool IsClosed
        {
            get
            {
                return string.Equals("closed", Status, StringComparison.InvariantCultureIgnoreCase);
            }
        }

        public bool IsAssignedToMe(Source source)
        {
            return string.Equals(Owner, source.UserName, StringComparison.InvariantCultureIgnoreCase);
        }

        public void InitializeOutlookTask(IOutlookItem outlookTask)
        {
            
        }

        public void UpdateOutlookTask(IOutlookItem outlookTask)
        {
            
        }
    }
}